package game.common.net;

import game.common.world.Point;
import game.common.world.PointImpl;
import game.common.world.Vector;
import game.common.world.VectorImpl;

import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;

import org.xsocket.connection.INonBlockingConnection;

public class GameHandler{

	/**
	 * during tests, first packet sent by server with a name and a vector 
	 */
	public static final short PTYPE_TEST_FIRST = 0x03;
	
	/**
	 * receives the position of the player, replies the position 
	 * 												some other objects around if necessary
	 * 										send the position to players around
	 */
	public static final short PTYPE_UPDATE_OBJECT_POSITION = 0x11;

	/**
	 * sends an object name to destroy to the client
	 */
	public static final short PTYPE_DESTROY_OBJECT = 0x12;
	
	// ********************** STRINGS **************************
	protected final String readPlayerName(INonBlockingConnection nbc) throws BufferUnderflowException, IOException{
		return nbc.readStringByLength(10).trim();
	}
	protected final void writePlayerName(String name , INonBlockingConnection nbc) throws BufferUnderflowException, IOException{
		int len = name.length();
		int diff = sizeOfPlayerName() - len;
		
		nbc.write(name);
		
		if (diff > 0){
			nbc.write(new byte[diff]);
		}
	}
	protected final int sizeOfPlayerName(){
		return 10;
	}
	
	// *********************** POINT ***************************
	protected final Point readPoint(INonBlockingConnection nbc) throws IOException{
		return new PointImpl((float)nbc.readDouble(),(float)nbc.readDouble(),(float)nbc.readDouble());
	}
	protected final void writePoint(Point p, INonBlockingConnection nbc) throws IOException{
		fsend(ByteBuffer.allocate(sizeOfPoint())
						.putDouble(p.getXf())
						.putDouble(p.getYf())
						.putDouble(p.getZf()),
			  nbc);
	}
	protected final int sizeOfPoint(){
		return 24;
	}

	// *********************** VECTOR ***************************
	protected final Vector readVector(INonBlockingConnection nbc) throws IOException{
		return new VectorImpl(new PointImpl((float)nbc.readDouble(),(float)nbc.readDouble(),(float)nbc.readDouble()),nbc.readShort(),nbc.readShort());
	}
	protected final void writeVector(Vector v, INonBlockingConnection nbc) throws IOException{
		fsend(ByteBuffer.allocate(sizeOfVector())
						.putDouble(v.getXf())
						.putDouble(v.getYf())
						.putDouble(v.getZf())
						.putShort((short)v.getDir())
						.putShort((short)v.getSpeed()),
			  nbc);
	}
	protected final int sizeOfVector(){
		return 28;
	}
	
	/**
	 * flips and sends the byte buffer
	 * 
	 * @param bb
	 */
	protected void fsend(ByteBuffer bb, INonBlockingConnection nbc) throws IOException{
		bb.flip();
		nbc.write(bb);
	}
}
